package com.cpx.config;

import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * @Auther: PanBin
 * @Date: 2018-8-24 15:34
 * @Description: mybatis包扫描配置
 * @Version: 1.0
 */
@Configuration
@MapperScan(value = "tk.mybatis.mapper.annotation")
public class MyBatisConfig {

    //常规配置
    /*@Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) {
        SqlSessionFactoryBean sqlSessionFactoryBean=new SqlSessionFactoryBean();
        try {
            sqlSessionFactoryBean.setDataSource(dataSource);
            // 设置别名包（实体类）
            sqlSessionFactoryBean.setTypeAliasesPackage("com.cpx.pojo");
            // 设置mybatis的主配置文件
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            //设置sql配置文件路径
            sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:com/cpx/mapper/*.xml"));
            //-- 加载mybatis的全局配置文件
            //Resource mybatisConfigXml = resolver.getResource("classpath:mybatis/mybatis-config.xml");
            //sqlSessionFactoryBean.setConfigLocation(mybatisConfigXml);
            return sqlSessionFactoryBean.getObject();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }*/

    //使用通用mapper
    @Bean(name = "trunkSqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(@Qualifier("trunkDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
        sessionFactory.setDataSource(dataSource);
        //加载mybatis的全局配置文件
       /* Resource mybatisConfigXml = resolver.getResource("classpath:mybatis/mybatis-config.xml");
        sessionFactory.setConfigLocation(mybatisConfigXml);*/
        //别名
        sessionFactory.setTypeAliasesPackage("com.cpx.pojo");
        // 设置mybatis的主配置文件
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        //设置sql配置文件路径
        sessionFactory.setMapperLocations(resolver.getResources("classpath:com/cpx/mapper/*.xml"));
        /*Configuration configuration = new Configuration();//tk.mybatis.mapper.session.Configuration
        //可以对 MapperHelper 进行配置后 set
        MapperHelper mapperHelper = new MapperHelper();
        configuration.setMapperHelper(mapperHelper);
        //设置为 tk 提供的 Configuration
        sessionFactory.setConfiguration(configuration);*/
        //配置mybatis分页插件,如果引入的是pagehelper-spring-boot-starter包，则如下插件配置可以省略
        //创建通用的分页对象
        PageInterceptor pageInterceptor = new PageInterceptor();
        //设置属性
        Properties properties = new Properties();
        //当 offsetAsPageNum=false 的时候，由于 PageNum 问题，RowBounds查询的时候 reasonable 会强制为 false。使用 PageHelper.startPage 方法不受影响。
        properties.setProperty("helperDialect","mysql"); //数据库及方言
        properties.setProperty("offsetAsPageNum","false");//默认值为 false，该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为 true 时，会将 RowBounds 中的 offset 参数当成 pageNum 使用，可以用页码和页面大小两个参数进行分页。
        properties.setProperty("rowBoundsWithCount","true");//默认值为false，该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为true时，使用 RowBounds 分页会进行 count 查询。
        //properties.setProperty("pageSizeZero","false");//pageSizeZero：默认值为 false，当该参数设置为 true 时，如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果（相当于没有执行分页查询，但是返回结果仍然是 Page 类型）。
        //properties.setProperty("reasonable","false");//分页合理化参数，默认值为false。当该参数设置为 true 时，pageNum<=0 时会查询第一页， pageNum>pages（超过总数时），会查询最后一页。默认false 时，直接根据参数进行查询。
        //properties.setProperty("params","false");//为了支持startPage(Object params)方法，增加了该参数来配置参数映射，用于从对象中根据属性名取值， 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable，不配置映射的用默认值， 默认值为pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero
        properties.setProperty("supportMethodsArguments","true");//支持通过 Mapper 接口参数来传递分页参数，默认值false，分页插件会从查询方法的参数值中，自动根据上面 params 配置的字段中取值，查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTest 和 ArgumentsObjTest。
        //properties.setProperty("autoRuntimeDialect","false");//默认值为 false。设置为 true 时，允许在运行时根据多数据源自动识别对应方言的分页 （不支持自动选择sqlserver2012，只能使用sqlserver），用法和注意事项参考下面的场景五。
        //properties.setProperty("closeConn","false");//默认值为 true。当使用运行时动态数据源或没有设置 helperDialect 属性自动获取数据库类型时，会自动获取一个数据库连接， 通过该属性来设置是否关闭获取的这个连接，默认true关闭，设置为 false 后，不会关闭获取的连接，这个参数的设置要根据自己选择的数据源来决定。
        pageInterceptor.setProperties(properties);
        //设置插件
        sessionFactory.setPlugins(new Interceptor[] {pageInterceptor});
        return sessionFactory.getObject();
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {//tk.mybatis.spring.mapper.MapperScannerConfigurer;
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("trunkSqlSessionFactory");
        mapperScannerConfigurer.setBasePackage("com.cpx.mapper");
        Properties properties = new Properties();
        properties.setProperty("mappers","com.cpx.BaseMapper");
        properties.setProperty("notEmpty","false");
        properties.setProperty("IDENTITY","MYSQL");
        mapperScannerConfigurer.setProperties(properties);
        return mapperScannerConfigurer;
    }
}
